import { ECurrentOperation, IImageState, IImageToolManage, ImageInfo, ZoomOperation } from '../types/jobs/images';
import Konva from 'konva';
import { Shape, ShapeConfig } from 'konva/lib/Shape';
import { Group } from 'konva/lib/Group';
import { browser } from '@/utils/http';
import svgUrl from '@/assets/images/home/close.svg';
const wPxRatio = () => document.body.clientWidth / 375;
const hPxRatio = () => document.body.clientHeight / 667;

/**
 * 图像工具
 */
export class ImageToolManage implements IImageToolManage {
  dom;
  /**图像编辑容器 */
  layers = [] as Array<Konva.Shape>;
  bgLayer: Konva.Layer = new Konva.Layer();
  stage;
  /**图像批改数据 */
  state;
  /**当前按钮互斥位置 */
  currentOperation = ECurrentOperation.none;
  /**当前激活的对象 */
  activeShape: Shape<ShapeConfig> | null = null;
  /** */
  static Instance: ImageToolManage;

  /**图像中心点*/
  constructor(state: ImageInfo, dom: HTMLDivElement) {
    this.state = state;
    this.dom = dom;
    const width = dom?.clientWidth || 375 * wPxRatio();
    const height = dom?.clientHeight || 466 * hPxRatio();
    this.stage = new Konva.Stage({
      container: dom,
      width,
      height,
      draggable: true,
      fill: 'white'
    });
    this.zoom = { ratio: 1, center: [width! / 2, height! / 2] };
    this.loadBgImageData().then((activeShape) => {
      const getDistance = (p1: { x: number; y: number }, p2: { x: number; y: number }) => {
        return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
      };
      let lastDist = 0;
      let lastScale = 1;
      /**多点 触摸缩放放大 */
      this.stage.getContent().addEventListener(
        'touchmove',
        function (evt) {
          let touch1 = evt.touches[0];
          let touch2 = evt.touches[1];

          if (touch1 && touch2 && activeShape) {
            let dist = getDistance(
              {
                x: touch1.clientX,
                y: touch1.clientY
              },
              {
                x: touch2.clientX,
                y: touch2.clientY
              }
            );

            if (!lastDist) {
              lastDist = dist;
            }

            let scale = (lastScale * dist) / lastDist;
            activeShape.scaleX(scale);
            activeShape.scaleY(scale);
            lastScale = scale;
            lastDist = dist;
          }
        },
        false
      );
      this.stage.getContent().addEventListener(
        'touchend',
        function () {
          lastDist = 0;
        },
        false
      );
      /**选择对象 */
      this.stage.on('tap', (evt: any) => {
        const shape = evt.target as Konva.Shape;
        this.stage.find('.rotatetransform').forEach((node) => node.remove());
        this.stage.find('.rotatetransformLayer').forEach((node) => node.remove());
        this.stage.find('.closeShapebtn').forEach((node) => node.remove());
        if (shape.name() == 'bgImage') {
          this.activeShape = null;
          return;
        }
        if (shape.name() == 'closeShapebtn') {
          this.stage.find('.rotatetransform').forEach((node) => node.remove());
          const idx = this.layers.findIndex((node) => node.name() === this.activeShape?.name());
          this.layers.splice(idx, 1);
          this.activeShape?.remove();
          shape.remove();
        }
        if (shape && shape.parent && shape.parent.name() != 'rotatetransform' && shape.name() != 'rotatetransform') {
          this.activeShape = shape;
          const layer = new Konva.Layer({ name: 'rotatetransformLayer' });
          const transform = new Konva.Transformer({
            nodes: [shape],
            centeredScaling: true,
            rotationSnaps: [0, 90, 180, 270],
            resizeEnabled: true,
            name: 'rotatetransform'
          });

          /**关闭按钮 */
          Konva.Image.fromURL(svgUrl, (imageNode: Shape<ShapeConfig> | Group) => {
            imageNode.setAttrs({
              name: 'closeShapebtn',
              x: -15,
              y: -40,
              width: 30,
              height: 30
            });
            transform.add(imageNode);
          });

          layer.add(transform);
          this.stage.add(layer);
        }
      });
      //拖拽初始化
      let con = this.stage.container();
      /**拖拽 贴图*/
      con.addEventListener('dragover', function (e) {
        e.preventDefault();
      });

      con.addEventListener('drop', (e: any) => {
        e.preventDefault();
        this.stage.setPointersPositions(e);
        if (!e.dataTransfer.getData('Text')) {
          return '';
        }
        const data: { url: string } = JSON.parse(e.dataTransfer.getData('Text'));
        Konva.Image.fromURL(data.url, (image: Konva.Image) => {
          const layer = new Konva.Layer();
          layer.add(image);
          image.position(this.stage.getPointerPosition()!);
          image.draggable(true);
        });
      });
    });
  }

  zoom: ZoomOperation;
  /**获取对象 */
  // static getInstance = (state: IImageState, dom: HTMLDivElement) => {
  //   if (!ImageToolManage.Instance) {
  //     ImageToolManage.Instance = new ImageToolManage(state, dom);
  //   }
  //   return ImageToolManage.Instance
  // }

  /**记载贴图 */
  loadImageData(url: string, name: string) {
    const layer = this.bgLayer;
    const imageObj = new Image();
    const bg = this.stage.find('.bgImage');
    const pos = { x: 0, y: 0 };
    if (bg.length > 0) {
      // 图像中间
      // pos.x = bg[0].position().x;
      // pos.y = bg[0].position().y;
      //屏幕中间
      pos.x = 120 - this.stage.x() + this.stage.offsetX();
      pos.y = 180 - this.stage.y() + this.stage.offsetY();
    }

    imageObj.onload = () => {
      const img = new Konva.Image({
        x: pos.x,
        y: pos.y,
        name,
        resizeEnabled: true,
        draggable: true,
        image: imageObj,
        width: 125 * wPxRatio(),
        height: 125 * hPxRatio()
      });

      // add the shape to the layer
      layer.add(img);
      this.layers.push(img);
    };
    imageObj.crossOrigin = 'Anonymous';
    imageObj.src = url;
  }

  /**背景图切换 */
  loadBgImageData(): Promise<Konva.Image> {
    return new Promise((resove, rej) => {
      this.stage.clearCache();
      this.stage.clear();
      const layer = this.bgLayer;

      const imageObj = new Image();
      imageObj.onload = () => {
        const bg = new Konva.Image({
          x: (imageObj.width * wPxRatio()) / 2,
          y: (imageObj.height * hPxRatio()) / 2,
          image: imageObj,
          width: imageObj.width * wPxRatio(),
          height: imageObj.height * hPxRatio(),
          rotationSnaps: [0, 90, 180, 270],
          name: 'bgImage',
          draggable: false,
          offset: { x: (imageObj.width * wPxRatio()) / 2, y: (imageObj.height * hPxRatio()) / 2 }
          // scale:{x:0.8,y:0.8}
        });
        // add the shape to the layer
        layer.add(bg);
        this.stage.offset({ x: (imageObj.width * wPxRatio()) / 4, y: (imageObj.height * hPxRatio()) / 4 });
        resove(bg);
      };
      imageObj.crossOrigin = 'Anonymous';
      //*默认批改过的
      imageObj.src = this.state.imgUrl || this.state.baseUrl;
      this.stage.add(layer);
    });
  }
  /**文字 */
  setText() {
    this.currentOperation = ECurrentOperation.none;
    const layer = this.bgLayer;
    const bg = this.stage.find('.bgImage');
    const pos = { x: 0, y: 0 };
    if (bg.length > 0) {
      // pos.x = bg[0].position().x;
      // pos.y = bg[0].position().y;
      //屏幕中间
      pos.x = 150 - this.stage.x() + this.stage.offsetX();
      pos.y = 250 - this.stage.y() + this.stage.offsetY();
    }
    const simpleText = new Konva.Text({
      x: pos.x,
      y: pos.y,
      name: 'simpleText',
      text: '双击修改',
      placeholder: '双击修改',
      fontFamily: 'Calibri',
      fill: 'red',
      fontSize: 22 * wPxRatio(),
      draggable: true,
      width: 150 * wPxRatio(),
      height: 31 * hPxRatio()
    });
    // const tr = new Konva.Transformer(
    //   {
    //     nodes: [simpleText],
    //     centeredScaling: true,
    //     resizeEnabled: true,
    //     enabledAnchors: ['middle-left', 'middle-right'],
    //     boundBoxFunc: function (oldBox, newBox) {
    //       newBox.width = Math.max(30, newBox.width);
    //       return newBox;
    //     },
    //   }
    // );

    simpleText.on('transform', function () {
      simpleText.setAttrs({
        width: simpleText.width() * simpleText.scaleX(),
        scaleX: 1
      });
    });

    simpleText.on('dblclick dbltap', () => {
      simpleText.hide();
      // tr.hide();
      let textPosition = simpleText.absolutePosition();

      let areaPosition = {
        x: this.stage.container().offsetLeft + textPosition.x,
        y: this.stage.container().offsetTop + textPosition.y
      };

      //创建可编辑区域
      let textarea = document.createElement('textarea');
      this.stage.container().append(textarea);

      textarea.value = simpleText.text() === '双击修改' ? '' : simpleText.text();
      textarea.style.position = 'absolute';
      textarea.style.top = areaPosition.y + 'px';
      textarea.style.left = areaPosition.x + 'px';
      textarea.style.width = simpleText.width() - simpleText.padding() * 2 + 'px';
      textarea.style.height = simpleText.height() - simpleText.padding() * 2 + 5 + 'px';
      textarea.style.fontSize = simpleText.fontSize() + 'px';
      textarea.style.border = 'none';
      textarea.style.padding = '0px';
      textarea.style.margin = '0px';
      textarea.style.overflow = 'hidden';
      textarea.style.background = 'none';
      textarea.style.outline = 'none';
      textarea.style.resize = 'none';
      textarea.style.lineHeight = simpleText.lineHeight().toString();
      textarea.style.fontFamily = simpleText.fontFamily();
      textarea.style.transformOrigin = 'left top';
      textarea.style.textAlign = simpleText.align();
      textarea.style.color = simpleText.fill();
      let rotation = simpleText.rotation();
      let transform = '';
      if (rotation) {
        transform += 'rotateZ(' + rotation + 'deg)';
      }

      let px = 0;
      // also we need to slightly move textarea on firefox
      // because it jumps a bit
      let isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
      if (isFirefox) {
        px += 2 + Math.round(simpleText.fontSize() / 20);
      }
      transform += 'translateY(-' + px + 'px)';

      textarea.style.transform = transform;

      // reset height
      textarea.style.height = 'auto';
      // after browsers resized it we can set actual value
      textarea.style.height = textarea.scrollHeight + 3 + 'px';

      textarea.focus();

      const removeTextarea = () => {
        textarea.parentNode?.removeChild(textarea);
        // window.removeEventListener('click', handleOutsideClick);
        simpleText.show();
        this.stage.off('tap.simpleText');
        // tr.show();
      };

      function setTextareaWidth(newWidth: any) {
        if (!newWidth) {
          // set width for placeholder
          newWidth = simpleText.placeholder.length * simpleText.fontSize();
        }
        // some extra fixes on different browsers
        let isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
        let isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
        if (isSafari || isFirefox) {
          newWidth = Math.ceil(newWidth);
        }

        let isEdge = document.DOCUMENT_NODE || /Edge/.test(navigator.userAgent);
        if (isEdge) {
          newWidth += 1;
        }
        textarea.style.width = newWidth + 'px';
      }
      const setOutsideClick = () => {
        if (simpleText && textarea) {
          simpleText.text(textarea.value === '' ? '双击修改' : textarea.value);
          simpleText.height(textarea.scrollHeight);
          removeTextarea();
          let scale = simpleText.getAbsoluteScale().x;
          setTextareaWidth(simpleText.width() * scale);
          textarea.style.height = 'auto';
          textarea.style.height = textarea.scrollHeight + 'px';
        }
      };

      textarea.addEventListener('focusout', function (e) {
        setOutsideClick();
      });
      this.stage.on('tap.simpleText', (e) => {
        if (browser.versions.android) {
          setOutsideClick();
        }
      });
    });
    //最后
    layer.add(simpleText);
    this.layers.push(simpleText);
  }
  /**回退 */
  backspacing() {
    this.currentOperation = ECurrentOperation.none;
    if (this.layers.length > 0) {
      const layer: Konva.Shape = this.layers.pop()!;
      if (layer) {
        layer.remove();
      }
    }
  }

  /**涂鸦 */
  brush() {
    //shape.draggable('true');
    this.currentOperation = ECurrentOperation.brush;
    const layer = this.bgLayer;

    // width:  375 * wPxRatio(),
    // height:  466 * hPxRatio(),
    let isPaint = false;
    let lastLine: Konva.Line;
    this.stage.draggable(false);
    this.stage.on('mousedown touchstart', (e) => {
      isPaint = true;
      const pos = this.stage.getRelativePointerPosition();
      lastLine = new Konva.Line({
        stroke: '#df4b26',
        strokeWidth: 7,
        globalCompositeOperation: 'source-over',
        // mode === 'brush' ? 'source-over' : 'destination-out',
        // round cap for smoother lines
        lineCap: 'round',
        lineJoin: 'round',
        draggable: true,
        // add point twice, so we have some drawings even on a simple click
        points: [pos!.x, pos!.y, pos!.x, pos!.y]
      });
      layer.add(lastLine);
      this.layers.push(lastLine);
    });

    this.stage.on('mouseup touchend', () => {
      isPaint = false;
    });

    // and core function - drawing
    this.stage.on('mousemove touchmove', (e) => {
      if (!isPaint) {
        return;
      }
      // prevent scrolling on touch devices
      e.evt.preventDefault();
      const pos = this.stage.getRelativePointerPosition();
      let newPoints = lastLine.points().concat([pos!.x, pos!.y]);
      lastLine.points(newPoints);
    });
  }

  /** 贴图 点击贴图 */
  chartlet() {
    this.stage.draggable(false);
    this.currentOperation = ECurrentOperation.chartlet;
  }
  /** 旋转 */
  rotate() {
    this.currentOperation = ECurrentOperation.none;
    //bgImage
    const bg = this.stage.find('.bgImage');
    bg.forEach((node) => {
      node.rotate(90);
    });
    // this.stage.rotate(90)
  }
  /** 回位 */
  flyback() {
    this.currentOperation = ECurrentOperation.none;
    this.stage.off('mousedown touchstart');
    this.stage.off('mouseup touchend');
    this.stage.off('mousemove touchmove');
    //清除旋转状态
    const tr = this.stage.find('.rotatetransform');
    tr.forEach((node) => node.remove());
    this.stage.find('.closeShapebtn').forEach((node) => node.remove());
    // this.layers.forEach(node => node.draggable(false));
    this.stage.draggable(true);
  }
  /** 答案 */
  answers() {
    this.currentOperation = ECurrentOperation.answers;
  }
  /**备课 */
  prepare() {
    this.currentOperation = ECurrentOperation.prepare;
  }
  /**打分 */
  mark() {
    this.currentOperation = ECurrentOperation.mark;
  }
}
